# 收集参数：可变参数
print("小甲鱼")
# 参数可多可少
print("小甲鱼", "爱", "编程")


def myfunc(*args):
    print(args)  # ('小甲鱼', '不二如是') 其实转换为了一个元组，因为元组有打包跟解包的能力
    print("有{}个参数。".format(len(args)))
    print("第二个参数是{}。".format(args[1]))


myfunc("小甲鱼", "不二如是")


def myfunc2():
    return 1, 2, 3  # 返回的时候会打包为一个元组


print(myfunc2())  # (1, 2, 3)

# 将函数返回的元组解包也是可以的
x, y, z = myfunc2()
print(x)
print(y)
print(z)


# 那么到这里，一个函数中的形参的定义形式为 *x 表示什么呢？
# 表示在传入函数的时候这个参数将会被打包到一个元组中,可以通过下面的方式证明

def myfunc3(*args):
    # 将收集参数打包为了一个元组
    print(type(args))  # <class 'tuple'>


myfunc3(1, 2, 3)  # <class 'tuple'>


# 但是 ，如果在收集参数之后还要传其他的参数，那么只能通过关键字参数来传了，否则就会被纳入到收集参数中

def myfunc4(*args, a, b):
    print(args, a, b)


# 参数 a, b 必须要传，否则报错
# myfunc4(1, 2, 3, 4, 5)  # TypeError: myfunc4() missing 2 required keyword-only arguments: 'a' and 'b'
myfunc4(1, 2, 3, b='b', a='c')  # (1, 2, 3) c b
